package org.openkoala.demo.facade.impl;

import java.util.List;
import java.util.ArrayList;
import java.text.MessageFormat;

import javax.inject.Inject;
import javax.inject.Named;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;
import org.dayatang.domain.InstanceFactory;
import org.dayatang.querychannel.Page;
import org.dayatang.querychannel.QueryChannelService;
import org.openkoala.demo.facade.dto.*;
import org.openkoala.demo.facade.impl.assmebler.EmployeeDtoAssembler;
import org.openkoala.demo.facade.EmployeeFacade;
import org.openkoala.demo.application.EmployeeApplication;
import org.openkoala.demo.core.domain.*;

@Named
@Transactional
public class EmployeeFacadeImpl implements EmployeeFacade {

	@Inject
	private EmployeeApplication  employeeApplication;

	private QueryChannelService queryChannel;

    private QueryChannelService getQueryChannelService(){
       if(queryChannel==null){
          queryChannel = InstanceFactory.getInstance(QueryChannelService.class,"queryChannel");
       }
     return queryChannel;
    }
	
	@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
	public EmployeeDTO getEmployee(Long id) {
		Employee employee =employeeApplication.getEmployee(id);
		return EmployeeDtoAssembler.EntityToDto(employee);
	}
	
	public EmployeeDTO saveEmployee(EmployeeDTO employeeDTO) {
		Employee employee = new Employee();
        employee=EmployeeDtoAssembler.DtoToEntity(employeeDTO);
		employeeApplication.saveEmployee(employee );
		employeeDTO.setId((java.lang.Long) employee.getId());
		return employeeDTO;
	}
	
	public void updateEmployee(EmployeeDTO employeeDTO) {
		Employee employee = Employee.get(Employee.class, employeeDTO.getId());
		employeeApplication.updateEmployee(EmployeeDtoAssembler.DtoToEntity(employeeDTO));
	}
	
	public void removeEmployee(Long id) {
			employeeApplication.removeEmployee( id );
	}
	
	public void removeEmployees(Long[] ids) {
		employeeApplication.removeEmployees( ids) ;
	}
	
	@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
	public List<EmployeeDTO> findAllEmployee() {
		List<EmployeeDTO> list = new ArrayList<EmployeeDTO>();
		List<Employee> all = Employee.findAll(Employee.class);
		for (Employee employee : all) {
			list.add(EmployeeDtoAssembler.EntityToDto( employee));
		}
		return list;
	}
	
	@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
	public Page<EmployeeDTO> pageQueryEmployee(EmployeeDTO queryVo, int currentPage, int pageSize) {
		List<EmployeeDTO> result = new ArrayList<EmployeeDTO>();
		List<Object> conditionVals = new ArrayList<Object>();
	   	StringBuilder jpql = new StringBuilder("select _employee from Employee _employee   where 1=1 ");
	   	if (queryVo.getName() != null) {
	   		jpql.append(" and _employee.name=?");
	   		conditionVals.add(queryVo.getName());
	   	}	
	   	if (queryVo.getName() != null && !"".equals(queryVo.getName())) {
	   		jpql.append(" and _employee.name like ?");
	   		conditionVals.add(MessageFormat.format("%{0}%", queryVo.getName()));
	   	}		
	   	if (queryVo.getAge() != null) {
	   		jpql.append(" and _employee.age=?");
	   		conditionVals.add(queryVo.getAge());
	   	}	
	   	if (queryVo.getGender() != null) {
	   		jpql.append(" and _employee.gender=?");
	   		conditionVals.add(queryVo.getGender());
	   	}	
	   	if (queryVo.getGender() != null && !"".equals(queryVo.getGender())) {
	   		jpql.append(" and _employee.gender like ?");
	   		conditionVals.add(MessageFormat.format("%{0}%", queryVo.getGender()));
	   	}		
        Page<Employee> pages = getQueryChannelService().createJpqlQuery(jpql.toString()).setParameters(conditionVals).setPage(currentPage, pageSize).pagedList();
        for (Employee employee : pages.getData()) {
           // 将domain转成VO 
                  
         EmployeeDTO employeeDTO = EmployeeDtoAssembler.EntityToDto(employee);       
                                                           result.add(employeeDTO);
        }
        return new Page<EmployeeDTO>(pages.getStart(), pages.getResultCount(), pageSize, result);
	}

	public void assignEmployeeToOrganization(EmployeeDTO employeeDto, Long organizationId) {
		employeeApplication.assignEmployeeToOrganization(EmployeeDtoAssembler.DtoToEntity(employeeDto),
				Organization.get(Organization.class, organizationId));		
	}

	public List<EmployeeDTO> findEmployeesByAgeRange(Integer from, Integer to) {
		List<EmployeeDTO> results = new ArrayList<EmployeeDTO>();
		for (Employee employee : employeeApplication.findEmployeesByAgeRange(from, to)) {
			results.add(EmployeeDtoAssembler.EntityToDto(employee));
		}
		return results;
	}
	
	
}
